/**
  ******************************************************************************
  * @file           : ECCOperator.cpp
  * @author         : sally
  * @brief          : None
  * @attention      : None
  * @date           : 24-11-11
  ******************************************************************************
  */



#include "ECCOperator.h"

// #include "Deleter.h"
// #include "Logging.h"

#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <memory>
#include <openssl/bn.h>
#include <openssl/core_names.h>
#include <openssl/crypto.h>
#include <openssl/ec.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/kdf.h>
#include <openssl/obj_mac.h>
#include <openssl/param_build.h>
#include <openssl/params.h>
#include <openssl/pem.h>
#include <openssl/sha.h>
#include <openssl/types.h>
#include <ostream>
#include <random>
#include <string>
#include <vector>
namespace droneswarm
{

    unsigned char *generate_salt( size_t length )
    {
        // 1.生成随机数种子
        std::random_device rd;
        // 2. 初始化随机数生成器
        std::mt19937 generator( rd() );
        std::uniform_int_distribution<> distribution( 0, 255 );

        unsigned char *salt = ( unsigned char * )OPENSSL_malloc( 16 );
        if ( !salt )
        {
            perror( "malloc" );
            return nullptr;
        }
        for ( size_t i = 0; i < length; ++i )
        {
            salt[ i ] = static_cast< unsigned char >( distribution( generator ) );
        }
        return salt;
    }

    std::string base64_encode( const unsigned char *data, size_t length )
    {
        BIO *bio, *b64;
        BUF_MEM *bufferPtr;

        b64 = BIO_new( BIO_f_base64() );
        bio = BIO_new( BIO_s_mem() );
        bio = BIO_push( b64, bio );

        BIO_set_flags( bio, BIO_FLAGS_BASE64_NO_NL );  // Do not add newlines
        BIO_write( bio, data, length );
        ( void )BIO_flush( bio );
        BIO_get_mem_ptr( bio, &bufferPtr );

        std::string encoded_data( bufferPtr->data, bufferPtr->length );
        BIO_free_all( bio );
        return encoded_data;
    }

    ECCOperator::ECCOperator()
        : q_( BN_new() )
        , n_( BN_new() )
        , a_( BN_new() )
        , b_( BN_new() )
        , P_( EC_POINT_new( nullptr ) )
        , curveAttributes_( EC_GROUP_new_by_curve_name( NID_X9_62_prime256v1 ) )
        , XP_( BN_new() )
        , YP_( BN_new() )
        , h_( BN_new() )
        , ctx_( BN_CTX_new() )
    {
        if ( !curveAttributes_ )
        {
            std::cerr << "Error creating EC_GROUP" << std::endl;
            exit( EXIT_FAILURE );
        }

        //获取素数q
        if ( !EC_GROUP_get_curve( curveAttributes_, q_, a_, b_, ctx_ ) )
        {
            std::cerr << "Error getting curve parameters" << std::endl;
            exit( EXIT_FAILURE );
        }

        //获取子群的阶和协因子h
        if ( !EC_GROUP_get_order( curveAttributes_, n_, ctx_ ) )
        {
            std::cerr << "Error getting order" << std::endl;
            exit( EXIT_FAILURE );
        }

        if ( !EC_GROUP_get_cofactor( curveAttributes_, h_, ctx_ ) )
        {
            std::cerr << "Error getting cofactor" << std::endl;
            exit( EXIT_FAILURE );
        }

        // EC_GROUP_get_cofactor( curveAttributes_, h_, ctx_ );

        //创建基点P_
        P_ = EC_POINT_new( curveAttributes_ );
        if ( !P_ )
        {
            std::cerr << "Error creating EC_POINT" << std::endl;
            exit( EXIT_FAILURE );
        }
        //获取并复制基点
        if ( !EC_POINT_copy( P_, EC_GROUP_get0_generator( curveAttributes_ ) ) )
        {
            std::cerr << "Error copying generator point" << std::endl;
            exit( EXIT_FAILURE );
        }

        //获取横纵坐标
        if ( !EC_POINT_get_affine_coordinates( curveAttributes_, P_, XP_, YP_, ctx_ ) )
        {
            std::cerr << "Error getting affine coordinates" << std::endl;
            exit( EXIT_FAILURE );
        }
    }
    ECCOperator::~ECCOperator()
    {
        BN_free( q_ );
        BN_free( n_ );
        BN_free( a_ );
        BN_free( b_ );
        BN_free( XP_ );
        BN_free( YP_ );
        BN_free( h_ );
        EC_GROUP_free( curveAttributes_ );
        EC_POINT_free( P_ );
        BN_CTX_free( ctx_ );
    }
    std::shared_ptr< BIGNUM > ECCOperator::GeneratePriKey()
    {
        //生成私钥
        //生成一个随机数k_priv，这个随机数的范围是(1,n)，n即曲线的阶
        //这样可能跟论文中的不一样，但是这个私钥的值虽然可能为1，但是是及其不安全的，因此当1作为私钥是非常弱的，会导致公钥等于基点，容易被攻击者利用。
        // BN_priv_rand_range(BIGNUM *rnd, const BIGNUM *range)
        BIGNUM *k_priv = BN_new();

        BIGNUM *one = BN_new();
        BIGNUM *n_minus_one = BN_new();

        if ( !k_priv || !one || !n_minus_one )
        {
            std::cerr << "Memory allocation failed" << std::endl;
            if ( k_priv )
                BN_free( k_priv );
            if ( one )
                BN_free( one );
            if ( n_minus_one )
                BN_free( n_minus_one );
            return nullptr;
        }

        //设置one的值为1
        BN_set_word( one, 1 );
        //减一得到范围

        BN_sub( n_minus_one, n_, one );  //大数减法运算
        int attempts = 0;
        const int max_attempts = 10;

        while ( true )
        {
            if ( !BN_priv_rand_range( k_priv, n_minus_one ) )
            {
                std::cerr << "Error generating random number" << std::endl;
                BN_free( k_priv );
                BN_free( one );
                BN_free( n_minus_one );
                return nullptr;
            }

            BN_add( k_priv, k_priv, one );  // 将范围 [0, n-1) 转换为 [1, n)

            if ( BN_cmp( k_priv, one ) > 0 && BN_cmp( k_priv, n_ ) < 0 )
            {
                break;  // 私钥在合法范围内，退出循环
            }

            if ( ++attempts >= max_attempts )
            {
                std::cerr << "Failed to generate valid private key after " << max_attempts << " attempts" << std::endl;
                BN_free( k_priv );
                BN_free( one );
                BN_free( n_minus_one );
                return nullptr;
            }
        }



        BN_free( one );
        BN_free( n_minus_one );
        return std::shared_ptr< BIGNUM >( k_priv, BnDeleter );
    }

    std::shared_ptr< EC_POINT > ECCOperator::GeneratePubKey( BIGNUM *PriKey )
    {

        //创建公钥并初始化
        EC_POINT *k_pub = EC_POINT_new( curveAttributes_ );

        //使用EC_POINT_mul函数来进行椭圆曲线点乘操作。
        /*

        函数原型：int EC_POINT_mul(const EC_GROUP *group,
                 EC_POINT *r,
                 const BIGNUM *n,
                 const EC_POINT *q,
                 const BIGNUM *m,
                 BN_CTX *ctx);
            group：一个 EC_GROUP 指针，表示椭圆曲线群。
            r：一个 EC_POINT 指针，表示结果点𝑅。
            n：一个 BIGNUM 指针，表示标量𝑘。
            q：一个 EC_POINT 指针，表示点𝑄。
            m：一个 BIGNUM 指针，表示标量𝑙。
            ctx：一个 BN_CTX 指针，用于临时变量的上下文。
            返回值：成功返回1，失败返回0
        */
        if ( EC_POINT_mul( curveAttributes_, k_pub, PriKey, nullptr, nullptr, ctx_ ) )
        {
            //还需要检查公钥是否是椭圆曲线加法循环群G上的点。
            //使用函数EC_POINT_is_on_curve
            int flag = EC_POINT_is_on_curve( curveAttributes_, k_pub, ctx_ );
            if ( flag == 1 )
            {
                std::cout << "The generated public key belongs to the elliptic curve additive cycle group, and the public "
                       "key(****************) is "
                       "generated successfully! "
                    << std::endl;
                return std::shared_ptr< EC_POINT >( k_pub, ECPointDeleter );
            }
            else
            {
                std::cout << "The generated public key does not belong to the elliptic curve additive cycle group, and the "
                       "public key generation failed! "
                    <<  std::endl;
                return nullptr;
            }
        }
        else
        {
             std::cout << "Public key calculation failed" << std::endl;
            return nullptr;
        }
    }

    std::shared_ptr< unsigned char > ECCOperator::EC_POINT2Char( EC_POINT *point, point_conversion_form_t form )
    {
        /*
           char *EC_POINT_point2hex(const EC_GROUP *group, const EC_POINT *point,point_conversion_form_t form, BN_CTX
           *ctx); 用于将椭圆曲线上的点（EC_POINT）转换为十六进制字符串表示。 group：一个 EC_GROUP 指针，表示椭圆曲线群。
            point：一个 EC_POINT 指针，表示要转换的椭圆曲线上的点。
            form：一个 point_conversion_form_t 类型，表示点的转换形式。常见的值有：
            POINT_CONVERSION_COMPRESSED：压缩形式。
            POINT_CONVERSION_UNCOMPRESSED：非压缩形式。
            POINT_CONVERSION_HYBRID：混合形式。
            ctx：一个 BN_CTX 指针，用于临时变量的上下文。可以为 NULL。
            返回值
            成功：返回一个指向以零结尾的字符串的指针，表示点的十六进制表示形式。需要调用 OPENSSL_free
           来释放返回的字符串。 失败：返回 NULL，表示转换失败。
       */
        unsigned char *Cpoint = ( unsigned char * )EC_POINT_point2hex( curveAttributes_, point, form, ctx_ );
        if ( Cpoint )
        {
            return std::shared_ptr< unsigned char >( Cpoint, UCharOpenSSlDeleter );
        }
        else
        {
            return nullptr;
        }
    }

    int
    ECCOperator::BN_ECKey_Conv_EC_EVPKey( BIGNUM *k_priv, EC_POINT *k_pub, EC_GROUP *group, EVP_PKEY **out_evp_pkey )
    {
        if ( !k_priv || !k_pub || !group || !out_evp_pkey )
        {
            std::cerr << "Null parameter provided to BN_ECKey_Conv_EC_EVPKey" << std::endl;
            return 0;
        }

        //准备EVP_PKEY_ctx上下文对象
        EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name( nullptr, "EC", nullptr );

        if ( !pctx )
        {
            handleOpenSSLErrors();
            // std::cout << "257" << std::endl;
            return 0;
        }
        // std::cout << "260" << std::endl;
        if ( EVP_PKEY_fromdata_init( pctx ) <= 0 )
        {
            // std::cout << "263" << std::endl;
            handleOpenSSLErrors();
            EVP_PKEY_CTX_free( pctx );
            return 0;
        }

        //提取公钥参数
        size_t k_pub_len = EC_POINT_point2oct( curveAttributes_, k_pub, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0, ctx_ );
        unsigned char *k_pub_c = ( unsigned char * )OPENSSL_malloc( k_pub_len );
        if ( !k_pub_c )
        {
            std::cout << "286" << std::endl;
            EVP_PKEY_CTX_free( pctx );
            handleOpenSSLErrors();
            return 0;
        }

        EC_POINT_point2oct( curveAttributes_, k_pub, POINT_CONVERSION_UNCOMPRESSED, k_pub_c, k_pub_len, ctx_ );

        OSSL_PARAM_BLD *param_bld;
        OSSL_PARAM *params = nullptr;
        param_bld = OSSL_PARAM_BLD_new();
        if ( k_priv != nullptr && param_bld != nullptr
             && OSSL_PARAM_BLD_push_utf8_string( param_bld, OSSL_PKEY_PARAM_GROUP_NAME, "prime256v1", 0 )
             && OSSL_PARAM_BLD_push_BN( param_bld, OSSL_PKEY_PARAM_PRIV_KEY, k_priv )
             && OSSL_PARAM_BLD_push_octet_string( param_bld, OSSL_PKEY_PARAM_PUB_KEY, k_pub_c, k_pub_len ) )
        {
            params = OSSL_PARAM_BLD_to_param( param_bld );
        }

        if (!params) {
            EVP_PKEY_CTX_free(pctx);
            OSSL_PARAM_BLD_free(param_bld);
            OPENSSL_free(k_pub_c);
            return 0;
        }

        //设置私钥和公钥的参数
        // OSSL_PARAM params[] = { OSSL_PARAM_construct_utf8_string(
        //                             OSSL_PKEY_PARAM_GROUP_NAME, ( char * )"prime256v1", 0 ),
        //                         OSSL_PARAM_construct_BN( OSSL_PKEY_PARAM_PRIV_KEY, k_priv_c, k_pri_len ),
        //                         OSSL_PARAM_construct_octet_string( OSSL_PKEY_PARAM_PUB_KEY, k_pub_c, k_pub_len ),
        //                         OSSL_PARAM_construct_end() };

        // std::cout << "342: " << params[ 1 ].data << std::endl;
        // unsigned char *bin = ( unsigned char * )params[ 1 ].data;

        // BIGNUM *bn3 = BN_new();
        // BN_bin2bn( bin, k_pri_len, bn3 );
        // std::cout << "349: " << BN_bn2hex( bn3 ) << std::endl;
        if ( EVP_PKEY_fromdata( pctx, out_evp_pkey, EVP_PKEY_KEYPAIR, params ) <= 0 )
        {
            // std::cout << "301" << std::endl;
            handleOpenSSLErrors();
             //OPENSSL_free( k_priv_c );
            OPENSSL_free( k_pub_c );
            EVP_PKEY_CTX_free( pctx );
            OSSL_PARAM_BLD_free(param_bld);
            OSSL_PARAM_free(params);
            return 0;
        }

        // EVP_PKEY *pkey = EVP_PKEY_new();
        // BIGNUM *bgn = BN_new();
        // EVP_PKEY_fromdata( pctx, &pkey, EVP_PKEY_KEYPAIR, params );
        // EVP_PKEY_get_bn_param( pkey, OSSL_PKEY_PARAM_PRIV_KEY, &bgn );
        // std::cout << "358: " << BN_bn2hex( bgn ) << std::endl;
        // const char *curve_name = OBJ_nid2sn( NID_X9_62_prime256v1 );
        // std::cout << "Using curve: " << curve_name << std::endl;
        //释放空间
        // OPENSSL_free( k_priv_c );
        OPENSSL_free( k_pub_c );
        EVP_PKEY_CTX_free( pctx );
        OSSL_PARAM_BLD_free(param_bld);
        OSSL_PARAM_free(params);
        return 1;
    }

    int ECCOperator::ECPubKey_Conv_EVPPubKey( EC_POINT *k_pub, EC_GROUP *group, EVP_PKEY **out_evp_pubkey )
    {
        //创建EVP_PKEY上下文对象
        EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name( nullptr, "EC", nullptr );

        if ( !pctx )
        {
            handleOpenSSLErrors();
            return 0;
        }
        //初始化上下文
        if ( EVP_PKEY_fromdata_init( pctx ) <= 0 )
        {
            handleOpenSSLErrors();
            return 0;
        }
        //将EC_POINT转换二进制转换为8进制
        size_t pubKeyLen = EC_POINT_point2oct( curveAttributes_, k_pub, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0, ctx_ );

        if ( pubKeyLen == 0 )
        {
            handleOpenSSLErrors();
            EVP_PKEY_CTX_free( pctx );
            return 0;
        }

        unsigned char *k_pub_c = ( unsigned char * )OPENSSL_malloc( pubKeyLen );
        if ( !k_pub_c )
        {
            EVP_PKEY_CTX_free( pctx );
            handleOpenSSLErrors();
            return 0;
        }

        EC_POINT_point2oct( curveAttributes_, k_pub, POINT_CONVERSION_UNCOMPRESSED, k_pub_c, pubKeyLen, ctx_ );

        //设置OSSL_PARAM params参数
        OSSL_PARAM params[] = { OSSL_PARAM_construct_utf8_string(
                                    OSSL_PKEY_PARAM_GROUP_NAME, ( char * )"prime256v1", 0 ),
                                OSSL_PARAM_construct_octet_string( OSSL_PKEY_PARAM_PUB_KEY, k_pub_c, pubKeyLen ),
                                OSSL_PARAM_construct_end() };

        if ( EVP_PKEY_fromdata( pctx, out_evp_pubkey, EVP_PKEY_KEYPAIR, params ) <= 0 )
        {
            handleOpenSSLErrors();
            OPENSSL_free( k_pub_c );
            EVP_PKEY_CTX_free( pctx );
            return 0;
        }

        OPENSSL_free( k_pub_c );
        EVP_PKEY_CTX_free( pctx );
        return 1;
    }

    int ECCOperator::deriveSymmetricKey( const EC_GROUP *group,
                                         const EC_POINT *pub_key,
                                         BIGNUM *priv_key,
                                         unsigned char *salt,
                                         unsigned char *out_key )
    {
        // const EC_GROUP *group  表示椭圆曲线群；const EC_POINT *pub_key 表示接收者的公钥； BIGNUM *priv_key
        // 表示发送者的私钥 unsigned char *out_key 表示输出的对称密钥 size_t out_len：表示对称密钥的长度。

        // 创建一个新的 EC_POINT 来存储计算结果

        if ( !priv_key )
        {
            std::cerr << "ERROR: priv_key is NULL" << std::endl;
            return 0;
        }

        EC_POINT *shared_point = EC_POINT_new( group );
        if ( !shared_point )
        {
            perror( "shared_point" );
            return 0;
        }
        // 计算共享秘密
        if ( !EC_POINT_mul( group, shared_point, nullptr, pub_key, priv_key, ctx_ ) )
        {
            perror( "EC_POINT_mul" );
            EC_POINT_free( shared_point );
            return 0;
        }
        // 将共享点转换为字节序列
        unsigned char *shared_secret = nullptr;
        int secret_len = EC_POINT_point2buf( group, shared_point, POINT_CONVERSION_UNCOMPRESSED, &shared_secret, ctx_ );
        if ( secret_len <= 0 )
        {
            perror( "EC_POINT_point2buf" );
            return 0;
        }

        //对共享秘密进行哈希处理以生成对称密钥
        // SHA256( shared_secret, secret_len, out_key );
        int ret =
            PKCS5_PBKDF2_HMAC( ( const char * )shared_secret, secret_len, salt, 16, 10000, EVP_sha256(), 32, out_key );
        if ( !ret )
        {
            handleOpenSSLErrors();
            EC_POINT_free( shared_point );
            OPENSSL_free( shared_secret );
            return 0;
        }
        EC_POINT_free( shared_point );
        OPENSSL_free( shared_secret );
        // std::cout << "会话密钥协商完毕" << std::endl;
        return 1;
    }

    // void ECCOperator::setSaltHash()
    // {

    //     unsigned int saltHashLen = salt_hash_length;
    //     saltHash_ = ( unsigned char * )OPENSSL_malloc( saltHashLen );

    //     if ( !EVP_Digest( salt_, 16, saltHash_, &saltHashLen, EVP_sha256(), NULL ) )
    //     {
    //         handleOpenSSLErrors();
    //     }
    // }

    //将EVP_PKEY提取成BIGNUM和EC_POINT类型的函数
    bool ECCOperator::extract_Pub_Priv_Frome_EVP_PKEY( EVP_PKEY *pkey, BIGNUM **priv, EC_POINT **pub, Model model )
    {
        if ( !pkey )
        {
            std::cout << "pkey is null" << std::endl;
            return false;
        }

        switch ( model )
        {
        case ONLYGETPRIKEY: {
            if ( EVP_PKEY_get_bn_param( pkey, OSSL_PKEY_PARAM_PRIV_KEY, priv ) != 1 )
            {
                std::cout << "Error: Failed to get private key" << std::endl;
                return false;
            }
            // std::cout << "Private key extracted successfully" << std::endl;
            break;
        }

        case ONLYGETPUBKEY: {
            size_t pub_len = 0;
            if ( EVP_PKEY_get_octet_string_param( pkey, OSSL_PKEY_PARAM_PUB_KEY, nullptr, 0, &pub_len ) != 1 )
            {
                std::cout << "Error: Failed to get public key length" << std::endl;
                return false;
            }
            unsigned char *pubkey_oct = ( unsigned char * )OPENSSL_malloc( pub_len );
            if ( !pubkey_oct )
            {
                std::cout << "Error: Failed to openssl_malloc" << std::endl;
                return false;
            }

            if ( EVP_PKEY_get_octet_string_param( pkey, OSSL_PKEY_PARAM_PUB_KEY, pubkey_oct, pub_len, &pub_len ) != 1 )
            {
                std::cout << "Error: Failed to get public key OCT" << std::endl;
                return false;
            }
            EC_POINT *pubkey = EC_POINT_new( getGroup() );
            if ( !pubkey )
            {
                std::cout << "Error: Failed to create EC_POINT" << std::endl;
                OPENSSL_free( pubkey_oct );
                return false;
            }
            //然后将字符串转换为EC_POINT
            if ( EC_POINT_oct2point( getGroup(), pubkey, pubkey_oct, pub_len, ctx_ ) != 1 )
            {
                std::cout << "Error: EC_POINT_oct2point" << std::endl;
                OPENSSL_free( pubkey_oct );
                EC_POINT_free( pubkey );
                return false;
            }
            *pub = pubkey;
            OPENSSL_free( pubkey_oct );
            // std::cout << "Public key extracted successfully" << std::endl;
            break;
        }

        case GETBOTH: {
            //处理私钥这部分
            if ( EVP_PKEY_get_bn_param( pkey, OSSL_PKEY_PARAM_PRIV_KEY, priv ) != 1 )
            {
                std::cout << "Error: Failed to get private key" << std::endl;
                return false;
            }
            // std::cout << "Private key extracted successfully" << std::endl;

            //处理公钥这部分
            size_t pub_len = 0;
            if ( EVP_PKEY_get_octet_string_param( pkey, OSSL_PKEY_PARAM_PUB_KEY, nullptr, 0, &pub_len ) != 1 )
            {
                std::cout << "Error: Failed to get public key length" << std::endl;
                return false;
            }
            unsigned char *pubkey_oct = ( unsigned char * )OPENSSL_malloc( pub_len );
            if ( !pubkey_oct )
            {
                std::cout << "Error: Failed to openssl_malloc" << std::endl;
                return false;
            }

            if ( EVP_PKEY_get_octet_string_param( pkey, OSSL_PKEY_PARAM_PUB_KEY, pubkey_oct, pub_len, &pub_len ) != 1 )
            {
                std::cout << "Error: Failed to get public key OCT" << std::endl;
                return false;
            }
            EC_POINT *pubkey = EC_POINT_new( getGroup() );
            if ( !pubkey )
            {
                std::cout << "Error: Failed to create EC_POINT" << std::endl;
                OPENSSL_free( pubkey_oct );
                return false;
            }
            //然后将字符串转换为EC_POINT
            if ( EC_POINT_oct2point( getGroup(), pubkey, pubkey_oct, pub_len, ctx_ ) != 1 )
            {
                std::cout << "Error: EC_POINT_oct2point" << std::endl;
                OPENSSL_free( pubkey_oct );
                EC_POINT_free( pubkey );
                return false;
            }
            *pub = pubkey;
            OPENSSL_free( pubkey_oct );
            // std::cout << "Public key extracted successfully" << std::endl;
            break;
        }
        default: {
            std::cerr << "Error: Unsupported key extraction model" << std::endl;
            return false;
        }
        }
        return true;
    }

    std::string ECCOperator::generateESDSASignature( EVP_PKEY *priKey, const std::string rawData )
    {

        //签名函数的函数原型EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen, const unsigned char
        //*tbs,
        // size_t tbslen)

        //创建EVP_MD_CTX *ctx
        EVP_MD_CTX *mctx = EVP_MD_CTX_new();
        if ( !mctx )
        {
            std::cout << "EVP_MD_CTX_new() 创建ctx失败" << std::endl;
            return "";
        }

        //使用EVP_sha256()函数来生成消息的摘要这个摘要应该能够代表原始消息的独一无二的指纹
        //摘要初始化

        if ( EVP_DigestSignInit( mctx, nullptr, EVP_sha256(), nullptr, priKey ) <= 0 )
        {
            std::cerr << "签名操作初始化失败" << std::endl;
            EVP_MD_CTX_free( mctx );
            return "";
        }

        size_t sign_len = 0;
        //将字符串转换为const unsigned char *
        size_t rawDataLength = rawData.size();

        //创建字符数组
        unsigned char rawDataArray[ rawDataLength ];
        memcpy( rawDataArray, rawData.c_str(), rawDataLength );

        //获取签名长度
        EVP_DigestSign( mctx, nullptr, &sign_len, rawDataArray, rawDataLength );

        //进行签名,

        unsigned char sign[ sign_len ];

        if ( EVP_DigestSign( mctx, sign, &sign_len, rawDataArray, rawDataLength ) <= 0 )
        {
            std::cerr << "产生签名失败" << std::endl;
            EVP_MD_CTX_free( mctx );
            return "";
        }

        //释放上下文
        EVP_MD_CTX_free( mctx );

        //构造签名的字符串
        std::string signDataStr( reinterpret_cast< const char * >( sign ), sign_len );
        return signDataStr;
    }

    bool ECCOperator::verifyEDSAsignature( EVP_PKEY *pubkey, const std::string &rawData, const std::string &signData )
    {
        if ( pubkey == nullptr )
        {
            std::cerr << "错误：公钥为空" << std::endl;
            return false;
        }

        EVP_MD_CTX *mctx = EVP_MD_CTX_new();
        if ( !mctx )
        {
            std::cerr << "错误：创建EVP_MD_CTX失败" << std::endl;
            return false;
        }

        if ( EVP_sha256() == nullptr )
        {
            std::cerr << "EVP_sha256() 返回 NULL" << std::endl;
        }

        if ( EVP_DigestVerifyInit( mctx, nullptr, EVP_sha256(), nullptr, pubkey ) <= 0 )
        {
            std::cerr << "错误：签名验证初始化失败" << std::endl;
            EVP_MD_CTX_free( mctx );
            return false;
        }

        const unsigned char *rawData_c = reinterpret_cast< const unsigned char * >( rawData.c_str() );
        size_t rawDataLength = rawData.size();

        const unsigned char *signData_c = reinterpret_cast< const unsigned char * >( signData.c_str() );
        size_t signLen = signData.size();

        if ( rawDataLength == 0 || signLen == 0 )
        {
            std::cerr << "错误：数据长度为零" << std::endl;
            EVP_MD_CTX_free( mctx );
            return false;
        }

        int ret = EVP_DigestVerify( mctx, signData_c, signLen, rawData_c, rawDataLength );
        if ( ret == 1 )
        {
            // std::cout << "签名验证通过" << std::endl;
            EVP_MD_CTX_free( mctx );
            return true;
        }
        else if ( ret == 0 )
        {
            std::cerr << "签名验证不通过，签名不一致" << std::endl;
            EVP_MD_CTX_free( mctx );
            return false;
        }
        else
        {  // std
            std::cerr << "EVP_DigestVerify函数错误" << std::endl;
            EVP_MD_CTX_free( mctx );
            unsigned long err_code = ERR_get_error();
            if ( err_code != 0 )
            {
                char err_msg[ 256 ];
                ERR_error_string_n( err_code, err_msg, sizeof( err_msg ) );
                fprintf( stderr, "错误信息: %s\n", err_msg );
            }
            return false;
        }
    }

    bool ECCOperator::computeSessionKey( EVP_PKEY *myPriKey, EVP_PKEY *peerPubKey, unsigned char **sessionKey )
    {

        EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new( myPriKey, nullptr );
        if ( !pctx )
        {
            ERR_print_errors_fp( stderr );
            return false;
        }

        //初始化密钥派生
        if ( EVP_PKEY_derive_init( pctx ) <= 0 )
        {
            ERR_print_errors_fp( stderr );
            EVP_PKEY_CTX_free( pctx );
            return false;
        }
        // std::cout << "1111" << std::endl;
        //设置对方的公钥
        if ( EVP_PKEY_derive_set_peer( pctx, peerPubKey ) <= 0 )
        {
            ERR_print_errors_fp( stderr );
            EVP_PKEY_CTX_free( pctx );
            return false;
        }

        size_t keyLen = 0;
        //确定派生密钥的长度
        if ( EVP_PKEY_derive( pctx, nullptr, &keyLen ) <= 0 )
        {
            ERR_print_errors_fp( stderr );
            EVP_PKEY_CTX_free( pctx );
            return false;
        }

        //创建密钥接收缓冲区
        unsigned char *sessKey = ( unsigned char * )OPENSSL_malloc( keyLen );

        if ( !sessKey )
        {
            ERR_print_errors_fp( stderr );
            EVP_PKEY_CTX_free( pctx );
            return false;
        }

        //派生密钥
        if ( EVP_PKEY_derive( pctx, sessKey, &keyLen ) <= 0 )
        {
            ERR_print_errors_fp( stderr );
            EVP_PKEY_CTX_free( pctx );
            OPENSSL_free( sessKey );
            return false;
        }

        EVP_PKEY_CTX_free( pctx );
        *sessionKey = sessKey;
        return true;
    }
}  // namespace droneswarm